<template>
	<div class="chat-box" @click="closeRefBox()" @mousemove="readedMessage()">
		<el-container>
			<el-header height="56px">
				<span>{{ title }}</span>
				<div class="header-actions">
					<span title="群聊消息" v-show="chat.type == 'GROUP'" class="btn-side" @click="toggleSide">
						<el-icon><Operation /></el-icon>
					</span>
				</div>
			</el-header>
			<el-main style="padding: 0;">
				<el-container>
					<el-container class="content-box">
						<el-main class="im-chat-main" id="chatScrollBox" ref="chatScrollBox" @scroll="onScroll">
							<div class="im-chat-box">
								<ul>
									<li v-for="(msgInfo, idx) in chat.messages" :key="idx">
										<chat-message-item
											v-if="idx >= showMinIdx"
											:id="'chat-message-' + idx + '-' + renderKey"
											:key="msgInfo.id + '-' + renderKey + '-' + (friend ? friend.headImage : '') + '-' + (friend ? friend.nickName : '')" 
											@call="onCall(msgInfo.type)"
											:mine="msgInfo.sendId == mine.id"
											:headImage="headImage(msgInfo)"
											:showName="showName(msgInfo)"
											:msgInfo="msgInfo"
											:isAdmin="isAdmin"
											:groupInfo="group.tempAutoAdd == 'Y'"
											:tagId="idx"
											:groupMembers="groupMembers"
											@delete="deleteMessage"
											@recall="recallMessage"
											@recallthis="onRecallthisMessage"
											@quote="onQuote"
											@forward="onForward">
										</chat-message-item>
									</li>
									<li ref="bottomAnchor" class="bottom-anchor"></li>
								</ul>
							</div>
						</el-main>
						<!-- height="240px" -->
						<el-footer :height="myheight" class="im-chat-footer">
							<div class="chat-tool-bar">
								<div title="表情" class="tool-icon-btn" ref="emotion" @click.stop="showEmotionBox()">
									<el-icon><StarFilled /></el-icon>
								</div>
								<!-- <div title="表情" class="icon el-icon-renqun" style="font-size: 20px;" ref="emotion"
									@click.stop="showEmotionBox()">
								</div> -->

								<div title="图片" class="tool-container">
									<file-upload :disabled="isProhibition" ref="uploadImage" :action="'/image/upload'" :maxSize="5 * 1024 * 1024"
										:fileTypes="['image/jpeg', 'image/png', 'image/jpg', 'image/webp', 'image/gif']"
										@before="onImageBefore" @success="onImageSuccess" @fail="onImageFail">
										<div class="tool-icon-btn" :class="{'disabled': isProhibition}">
											<el-icon><Picture /></el-icon>
										</div>
									</file-upload>
								</div>
								
								<div title="文件" class="tool-container">
									<file-upload :disabled="isProhibition" ref="fileUpload" :action="'/file/upload'" :maxSize="10 * 1024 * 1024"
										@before="onFileBefore" @success="onFileSuccess" @fail="onFileFail" @preview="onPreviewImage">
										<div class="tool-icon-btn" :class="{'disabled': isProhibition}">
											<el-icon><Document /></el-icon>
										</div>
									</file-upload>
								</div>
								
								<div title="回执" v-if="chat.type == 'GROUP'" class="tool-icon-btn" 
									:class="{'active': isReceipt}" 
									@click="onSwitchReceipt">
									<el-icon><Reading /></el-icon>
								</div>
								
								<div title="语音" class="tool-container">
									<div class="tool-icon-btn" @click="showRecordBox()">
										<el-icon><Microphone /></el-icon>
									</div>
								</div>
								
								<div title="视频" class="tool-container">
									<div class="tool-icon-btn" @click="onGroupVideo()">
										<el-icon><VideoCamera /></el-icon>
									</div>
								</div>
								
								<div title="历史" class="tool-icon-btn" @click="showHistoryBox()">
									<el-icon><ChatDotRound /></el-icon>
								</div>
							</div>
							<div class="send-content-area" @drop="handleDrop" @dragover="allowDrop">
								<!-- isadmin    :key="`chat-input-${isProhibition}-${Date.now()}`"-->
								<ChatInput  
									
									:tipText="sendText" 
									:prohibition="isProhibition" 
									:chatType="chat.type" 
									v-show="!sendImageUrl" 
									:ownerId="group.ownerId+''" 
									ref="chatInputEditor" 
									:group-members="groupMembers"
									@submit="sendMessage" 
									@selffocus="onFocus"  
								/>
									<div v-show="sendImageUrl" class="send-image-area">
										<div class="chat-msg-file">
											<div class="chat-file-box" >
												<div class="chat-file-info">
													<el-link class="chat-file-name" :underline="true" target="_blank" type="primary"
														href="data.url">{{snedFileName}}</el-link>
													<div class="chat-file-size"></div>
													{{ snedFileSize}}
												</div>
												<div class="chat-file-icon">
													<img class="send-image" style="width: 65px;height: 65px;" element-loading-background="rgba(0, 0, 0, 0.4)" :src="sendImageUrl" />

												</div>
												<div class="delete-icon" @click="removeSendImage">
													<el-icon><Close /></el-icon>
												</div>
											</div>
										</div>
										<!-- <div class="send-image-box">
											<img class="send-image" style="width: 65px;height: 65px;" :src="sendImageUrl" />
											<span
											class="send-image-close el-icon-close"
											title="删除"
											@click="removeSendImage()"
											></span>
										</div> -->
									</div>
								<div class="send-btn-area">
									<el-button  v-if="this.chat.type == 'GROUP'" type="primary" size="small" @click="notifySend()" :disabled="isProhibition">发送</el-button>
									<el-button  v-if="this.chat.type != 'GROUP'" type="primary" size="small" @click="notifySend()" >发送</el-button>
									<!-- <el-button  type="primary" size="small" @click="notifySend()" >发送</el-button> -->
								</div>
							</div>
						</el-footer>
					</el-container>
					<el-aside width="300px" v-if="showSide && chat.type != 'GROUP'" style="overflow-y: auto; padding: 0px;">
						<!-- 注意：对于群聊，我们在el-drawer中使用了ChatGroupSide组件，这里不应再次使用 -->
						<!-- 在这里可以放非群聊时需要的侧边栏内容 -->
					</el-aside>
				</el-container>
			</el-main>
		</el-container>
		
		<!-- 将侧边栏移出主容器，改为 el-drawer -->
		<el-drawer
			v-model="showSide"
			:with-header="false"
			:size="430"
			direction="rtl"
			:destroy-on-close="false"
			:modal="false"
			:show-close="true"
			:close-on-press-escape="true"
			:close-on-click-modal="false"
			v-if="chat.type == 'GROUP'">
			<chat-group-side 
				:group="group" 
				:groupMembers="groupMembers" 
				@reload="group && group.id ? loadGroup(group.id) : null"
				@close="showSide = false">
			</chat-group-side>
		</el-drawer>
		
		<emotion ref="emoBox" @emotion="onEmotion"></Emotion>
		<chat-record :visible="showRecord" @close="closeRecordBox" @send="onSendRecord"></chat-record>
		<group-member-selector ref="rtcSel" :groupId="group && group.id ? group.id+'' : ''" @complete="onInviteOk"></group-member-selector>
		<rtc-group-join ref="rtcJoin" :groupId="group && group.id ? group.id : ''"></rtc-group-join>
		<chat-history 
			v-model="showHistory"
			:mysize="myheight=='240px'?'600px':'330px'" 
			:chat="chat" 
			:friend="friend" 
			:group="group"
			:groupMembers="groupMembers" 
			@close="closeHistoryBox">
		</chat-history>
		
		<!-- 转发消息组件 -->
		<forward-dialog 
			v-model="showForwardDialog"
			:message="currentMSGObj"
			@close="showForwardDialog = false">
		</forward-dialog>
		
		<!-- 临时转发对话框解决方案 -->
		<temp-forward-dialog
			v-model="showTempForwardDialog"
			:message="currentMSGObj"
			@forward-complete="onForwardComplete">
		</temp-forward-dialog>
	</div>
</template>

<script>
	import ChatMessageItem from './ChatMessageItem.vue';
	import ChatHistory from './ChatHistory.vue';
	import ChatGroupSide from './ChatGroupSide.vue';
	import ChatRecord from './ChatRecord.vue';
	import ForwardDialog from './ForwardDialog.vue';
	import TempForwardDialog from './TempForwardDialog.vue';
	import FileUpload from "../common/FileUpload.vue";
	import Emotion from "../common/Emotion.vue";
	import ChatAtBox from "./ChatAtBox.vue"
	import GroupMemberSelector from "../group/GroupMemberSelector.vue"
	import RtcGroupJoin from "../rtc/RtcGroupJoin.vue"
	import ChatInput from "./ChatInput.vue";
	import * as fileIcon from '@/utils/fileIcon.js';
	import groupApi from '@/api/im/group';
	import groupMemberApi from "@/api/im/groupMemberApi";
	import { title } from "process";
	import emitter from '@/utils/eventBus';
	import { 
		Wallet, 
		ChatDotRound,
		Operation,
		Microphone,
		VideoCamera,
		StarFilled,
		Picture,
		Reading,
		Close
	} from '@element-plus/icons-vue';

	export default {
		name: "chatPrivate",
		components: {
			ChatInput,
			ChatMessageItem,
			FileUpload,
			ChatGroupSide,
			Emotion,
			ChatRecord,
			ChatHistory,
			ChatAtBox,
			GroupMemberSelector,
			RtcGroupJoin,
			ForwardDialog,
			TempForwardDialog,
			// 注册图标组件
			Wallet,
			ChatDotRound,
			Operation,
			Microphone,
			VideoCamera,
			StarFilled,
			Picture,
			Reading,
			Close
		},
		props: {
			chat: {
				type: Object
			},
			flag:{
				type:Boolean
			},
			myheight:{
				type:String,
				default:"240px"
			}
		},
		data() {
			return {
				gAPI: new groupApi(), // 群API
				gmAPI: new groupMemberApi(),// 群成员API
				draggedFile: null, // 用于存储拖拽的文件
				friend: {},
				group: {},
				groupMembers: [],
				sendImageUrl: "",
				snedFileName: "",
				snedFileSize: "",
				sendImageFile: "",
				placeholder: "",
				isReceipt: false,
				showRecord: false, // 是否显示语音录制弹窗
				showSide: false, // 是否显示群聊信息栏
				showHistory: false, // 是否显示历史聊天记录
				lockMessage: false, // 是否锁定发送，
				showMinIdx: 0, // 下标低于showMinIdx的消息不显示，否则页面会很卡置
				reqQueue: [],
				isSending : false,
				renderKey: 0, // 用于强制重新渲染消息组件
				// 以下变量新曾
				isadmin:false,
				isProhibition:false,
				stylea:'left',
				AutoAdd:false,
				quoteShow:false,
				closable:true,
				value4:'',
				targetId:"",
				quoteId:'',
				currentMSGObj: {}, // 当前需要转发的消息对象
				sendText: '',
				scrollThrottleTimer: null,
				messageChunkSize: 20,
				visibleMessages: [],
				observerOptions: {
					root: null,
					rootMargin: '20px',
					threshold: 0.1
				},
				activeTab: 'info',
				isLoading: false,
				domObserver: null,
				contentLoading: false, // 内容加载状态
				membersLoading: false, // 成员加载状态
				friendLoadTimer: null, // 添加防抖计时器
				friendUpdateTimer: null, // 添加更新防抖计时器
				lastFriendId: null, // 记录上一次加载的好友ID
				showForwardDialog: false, // 转发对话框状态，默认为隐藏
				showTempForwardDialog: false // 临时转发对话框状态，默认为隐藏
			}
		},
		created() {
			// 创建节流的滚动处理函数
			this.throttledScrollHandler = this.throttle(this.onScroll, 200);
		},
		methods: {
			positioningMsg(){//定位消息
				if(this.targetId==""){
					return;
				}
			  const target = document.getElementById('chat-item-'+(this.targetId-3));
					target.scrollIntoView({
						behavior: 'smooth'
					});
				this.targetId="";
			},
			onForward(magInfo){//转发
				console.log('转发消息:', magInfo);
				this.currentMSGObj = magInfo;//把传过来的消息对象赋值给当前消息对象，用于发送消息
				
				// 确保消息对象有效
				if (!this.currentMSGObj) {
					console.error('转发消息对象为空');
					return;
				}
				
				// 仅显示新的转发对话框
				this.showTempForwardDialog = true;
				console.log('已设置临时转发对话框状态:', this.showTempForwardDialog);
				
				// 确保状态更新后DOM已渲染
				this.$nextTick(() => {
					// 强制重新渲染
					this.$forceUpdate();
				});
			},
			onForwardComplete(selectItem){//回调   转发消息
			let msgInfo={};
			let type =this.currentMSGObj.type;
			let content=this.currentMSGObj.content;
				selectItem.forEach((item)=>{
					msgInfo={};
					if (item.type == "GROUP") {
						msgInfo.groupId = item.targetId;
					} else {
						msgInfo.recvId = item.targetId;
					}
					msgInfo.chatType=item.type;
					if(type==this.$enums.MESSAGE_TYPE.TEXT){//文字
						 msgInfo.content=content;
						 msgInfo.atUserIds= this.atUserIds;
						 msgInfo.sendTime = new Date().getTime();
						 msgInfo.receipt=false;
						 msgInfo.type=0;
						this.sendMessageRequest2(msgInfo).then((m) => {
							this.$notify({
							title: '提示',
								message: '已发送!'
							});	
						});
							
					}else if(type==this.$enums.MESSAGE_TYPE.IMAGE){//图片
						msgInfo.id=0;
						msgInfo.tmpId = this.generateId();
						msgInfo.fileId = null;
						msgInfo.sendId = this.mine.id;
						msgInfo.content = content;
						msgInfo.sendTime = new Date().getTime();
						msgInfo.selfSend = true;
						msgInfo.type = this.$enums.MESSAGE_TYPE.IMAGE;
						msgInfo.readedCount = 0;
						msgInfo.loadStatus =  "loading";
						msgInfo.status = this.$enums.MESSAGE_STATUS.UNSEND;
						this.sendMessageRequest2(msgInfo).then((m) => {
								this.$notify({
								title: '提示',
									message: '已发送!'
								});	
							});
					}else if(type==this.$enums.MESSAGE_TYPE.FILE){//文件
						msgInfo.id = 0;
						msgInfo.tmpId = this.generateId(),
						msgInfo.sendId = this.mine.id,
						msgInfo.content = content,
						msgInfo.sendTime = new Date().getTime(),
						msgInfo.selfSend = true,
						msgInfo.type = this.$enums.MESSAGE_TYPE.FILE,
						msgInfo.readedCount = 0,
						msgInfo.loadStatus = "loading",
						msgInfo.status = this.$enums.MESSAGE_STATUS.UNSEND
						this.sendMessageRequest2(msgInfo).then((m) => {
								this.$notify({
								title: '提示',
									message: '已发送!'
								});	
							});
					}else if(type==this.$enums.MESSAGE_TYPE.AUDIO){//语音
						msgInfo = {
							content:content ,
							type: this.$enums.MESSAGE_TYPE.AUDIO,
							receipt: false
						}
						this.sendMessageRequest2(msgInfo).then((m) => {
							this.$notify({
							title: '提示',
								message: '已发送!'
							});	
						});
					}else if(type==this.$enums.MESSAGE_TYPE.ACT_RT_VOICE){//电话
						console.log('暂不做处理');
					}else if(type==this.$enums.MESSAGE_TYPE.ACT_RT_VIDEO){//视频
						console.log('暂不做处理');
					}
				})
			},
			onQuote(quoteMessage) {
				// 构建引用消息
				const msgInfo = {
					type: this.$enums.MESSAGE_TYPE.TEXT,
					content: '',  // 内容由输入框填写
					chatType: this.chat.type,
					recvId: this.chat.type === 'PRIVATE' ? this.chat.targetId : undefined,
					groupId: this.chat.type === 'GROUP' ? this.chat.targetId : undefined,
					quoteMessage: {
						id: quoteMessage.id,
						type: quoteMessage.type,
						content: quoteMessage.content,
						sendNickName: quoteMessage.sendNickName
					}
				};

				// 将引用消息传递给输入框组件
				if (this.$refs.chatInputEditor) {
					this.$refs.chatInputEditor.setQuoteMessage(msgInfo);
				}
			},
			onPreviewImage(url){
				if(url){
					this.sendImageUrl=url;
				}
			},
			allowDrop(event) {
      			event.preventDefault();
    		},
			handleDrop(event) {
				event.preventDefault();
				const file = event.dataTransfer.files[0];
				if(this.isFile(file)){
					this.draggedFile=file;
					this.snedFileSize=file.size;
					this.snedFileName=file.name;
					this.sendImageUrl = fileIcon.getUrl(file.path); //'https://bpic.51yuansu.com/pic2/cover/00/30/54/581086ae534a4_610.jpg'; // 在输入框显示文件图标
				}else{
					this.draggedFile=file;
					this.$refs.fileUpload.handleFileChange(file);
					//this.$refs.uploadImage.handleFileChange(file);
				}
    		},
			isFile(file) {
				if (file.type.startsWith("image/")) {
					return false
				} else {
					return true
				}
			},
			removeSendImage() {
				this.sendImageUrl = "";
				this.sendImageFile = null;
				this.draggedFile = null;
				this.snedFileName = "";
				this.snedFileSize = "";
			},
			moveChatToTop() {
				let chatIdx = this.$store.getters.findChatIdx(this.chat);
				this.$store.commit("moveTop", chatIdx);
			},
			closeRefBox() {
				this.$refs.emoBox.close();
				// this.$refs.atBox.close();
			},
			onCall(type) {
				if (type == this.$enums.MESSAGE_TYPE.ACT_RT_VOICE) {
					this.showPrivateVideo('voice');
				} else if (type == this.$enums.MESSAGE_TYPE.ACT_RT_VIDEO) {
					this.showPrivateVideo('video');
				}
			},
			onSwitchReceipt() {
				if(this.isProhibition){
					return;
				}
				this.isReceipt = !this.isReceipt;
				this.refreshPlaceHolder();
			},
			onImageSuccess(data, file) {
				let msgInfo = JSON.parse(JSON.stringify(file.msgInfo));
				msgInfo.content = JSON.stringify(data);
				msgInfo.receipt = this.isReceipt;
				
				// 如果有引用消息ID,添加到发送参数中
				if (this.$refs.chatInputEditor.quoteMessage) {
					msgInfo.quoteId = this.$refs.chatInputEditor.quoteMessage.quoteMessage.id;
				}

				this.sendMessageRequest(msgInfo).then((m) => {
					msgInfo.loadStatus = 'ok';
					msgInfo.id = m.id;
					this.isReceipt = false;
					this.$store.commit("insertMessage", msgInfo);
				});
			},
			onImageFail(e, file) {
				let msgInfo = JSON.parse(JSON.stringify(file.msgInfo));
				msgInfo.loadStatus = 'fail';
				this.$store.commit("insertMessage", msgInfo);
			},
			onImageBefore(file) {
				let url = URL.createObjectURL(file);
				let data = {
					originUrl: url,
					thumbUrl: url
				}
				let msgInfo = {
					id: 0,
					tmpId: this.generateId(),
					fileId: file.uid,
					sendId: this.mine.id,
					content: JSON.stringify(data),
					sendTime: new Date().getTime(),
					selfSend: true,
					type: 1,
					readedCount: 0,
					loadStatus: "loading",
					status: this.$enums.MESSAGE_STATUS.UNSEND,
					quoteId: this.$refs.chatInputEditor.quoteMessage?.quoteMessage?.id
				}
				// 填充对方id
				this.fillTargetId(msgInfo, this.chat.targetId);
				// 插入消息
				this.$store.commit("insertMessage", msgInfo);
				// 会话置顶
				this.moveChatToTop();
				// 滚动到底部
				this.scrollToBottom();
				// 借助file对象保存
				file.msgInfo = msgInfo;
			},
			onFileSuccess(url, file) {
				let data = {
					name: file.name,
					size: file.size,
					url: url
				}
				let msgInfo = JSON.parse(JSON.stringify(file.msgInfo));
				msgInfo.content = JSON.stringify(data);
				msgInfo.receipt = this.isReceipt;
				
				// 如果有引用消息ID,添加到发送参数中
				if (this.$refs.chatInputEditor.quoteMessage) {
					msgInfo.quoteId = this.$refs.chatInputEditor.quoteMessage.quoteMessage.id;
				}

				this.sendMessageRequest(msgInfo).then((m) => {
					msgInfo.loadStatus = 'ok';
					msgInfo.id = m.id;
					this.isReceipt = false;
					this.refreshPlaceHolder();
					this.$store.commit("insertMessage", msgInfo);
				});
			},
			onFileFail(e, file) {
				let msgInfo = JSON.parse(JSON.stringify(file.msgInfo));
				msgInfo.loadStatus = 'fail';
				this.$store.commit("insertMessage", msgInfo);
			},
			onFileBefore(file) {
				let url = URL.createObjectURL(file);
				let data = {
					name: file.name,
					size: file.size,
					url: url
				}
				let msgInfo = {
					id: 0,
					tmpId: this.generateId(),
					sendId: this.mine.id,
					content: JSON.stringify(data),
					sendTime: new Date().getTime(),
					selfSend: true,
					type: 2,
					loadStatus: "loading",
					readedCount: 0,
					status: this.$enums.MESSAGE_STATUS.UNSEND,
					quoteId: this.$refs.chatInputEditor.quoteMessage?.quoteMessage?.id
				}
				// 填充对方id
				this.fillTargetId(msgInfo, this.chat.targetId);
				// 插入消息
				this.$store.commit("insertMessage", msgInfo);
				// 会话置顶
				this.moveChatToTop();
				// 滚动到底部
				this.scrollToBottom();
				// 借助file对象透传
				file.msgInfo = msgInfo;
			},
			onCloseSide() {
				this.showSide = false;
			},
			onScrollToTop() {
				// 多展示10条信息
				this.showMinIdx = this.showMinIdx > 10 ? this.showMinIdx - 10 : 0;
			},
			onScroll(e) {
				const scrollElement = e.target;
				const scrollTop = scrollElement.scrollTop;
				const clientHeight = scrollElement.clientHeight;
				const scrollHeight = scrollElement.scrollHeight;

				// 处理向上滚动加载更多
				if (scrollTop < 30) {
					this.showMinIdx = Math.max(0, this.showMinIdx - this.messageChunkSize);
					this.updateVisibleMessages();
					
					// 保持滚动位置
					this.$nextTick(() => {
						scrollElement.scrollTop = 50;
					});
				}

				// 处理向下滚动到底部
				if (scrollHeight - scrollTop - clientHeight < 50) {
					this.loadMoreMessages();
				}
			},
			showEmotionBox() {
				if(this.isProhibition){
					return;
				}
				let width = this.$refs.emotion.offsetWidth;
				let left = this.$elm.fixLeft(this.$refs.emotion);
				let top = this.$elm.fixTop(this.$refs.emotion);
				this.$refs.emoBox.open({
					x: left + width / 2,
					y: top
				})
			},
			onEmotion(emoText) {
				this.$refs.chatInputEditor.insertEmoji(emoText);
			},
			showRecordBox() {
				this.showRecord = true;
			},
			closeRecordBox() {
				this.showRecord = false;
			},
			showPrivateVideo(mode) {
				let rtcInfo = {
					mode: mode,
					isHost: true,
					friend: this.friend,
				}
				// 通过home.vue打开单人视频窗口
				this.$eventBus.$emit("openPrivateVideo", rtcInfo);
			},
			onGroupVideo() {
				this.$http({
					url: "/webrtc/group/info?groupId=" + this.group.id,
					method: 'GET'
				}).then((rtcInfo) => {
					if (rtcInfo.isChating) {
						// 已在通话中，可以直接加入通话
						this.$refs.rtcJoin.open(rtcInfo);
					} else {
						// 邀请成员发起通话
						let ids = [this.mine.id];
						let maxChannel = this.$store.state.configStore.webrtc.maxChannel;
						this.$refs.rtcSel.open(maxChannel, ids, ids);
					}
				})

			},
			onInviteOk(members) {
				if (members.length < 2) {
					return;
				}
				let userInfos = [];
				members.forEach(m => {
					userInfos.push({
						id: m.userId,
						nickName: m.showNickName,
						headImage: m.headImage,
						isCamera: false,
						isMicroPhone: true
					})
				})
				let rtcInfo = {
					isHost: true,
					groupId: this.group.id,
					inviterId: this.mine.id,
					userInfos: userInfos
				}
				// 通过home.vue打开多人视频窗口
				this.$eventBus.$emit("openGroupVideo", rtcInfo);
			},
			showHistoryBox() {
				this.showHistory = true;
			},
			closeHistoryBox() {
				this.showHistory = false;
			},
			onSendRecord(data) {
				let msgInfo = {
					content: JSON.stringify(data),
					type: 3,
					receipt: this.isReceipt
				}
				// 填充对方id
				this.fillTargetId(msgInfo, this.chat.targetId);
				this.sendMessageRequest(msgInfo).then((m) => {
					m.selfSend = true;
					this.$store.commit("insertMessage", m);
					// 会话置顶
					this.moveChatToTop();
					// 保持输入框焦点
					this.$refs.chatInputEditor.focus();
					// 滚动到底部
					this.scrollToBottom();
					// 关闭录音窗口
					this.showRecord = false;
					this.isReceipt = false;
					this.refreshPlaceHolder();
				})
			},
			fillTargetId(msgInfo, targetId) {
				if (this.chat.type == "GROUP") {
					msgInfo.groupId = targetId;
				} else {
					msgInfo.recvId = targetId;
				}
			},
			notifySend() {
				this.$refs.chatInputEditor.submit();
			},
			async sendMessage(fullList) {
				if(this.draggedFile){
					this.sendImageUrl=''
					if(!this.isFile(this.draggedFile)){
						await this.sendImageMessage(this.draggedFile);
					}else{
						await this.sendFileMessage(this.draggedFile);
					}
					
				}else{
					this.resetEditor();
					this.readedMessage();
					let sendText = this.isReceipt ? "【回执消息】" : "";
					let promiseList = [];
					for (let i = 0; i < fullList.length; i++) {
						let msg = fullList[i];
						switch (msg.type) {
							case "text":
								await this.sendTextMessage(sendText + msg.content,msg.atUserIds);
								break;
							case "image":
								await this.sendImageMessage(msg.content.file);
								break;
							case "file":
								await this.sendFileMessage(msg.content.file);
								break;
						}
					}
				}
				
				// 确保滚动到底部
				this.scrollToBottom();
			},
			sendImageMessage(file) {
				return new Promise((resolve,reject)=>{
					this.onImageBefore(file);
					let formData = new FormData()
					formData.append('file', file)
					this.$http.post("/image/upload", formData, {
						headers: {
							'Content-Type': 'multipart/form-data'
						}
					}).then((data) => {
						this.onImageSuccess(data, file);
						this.sendImageUrl = "";
						resolve();
					}).catch((res) => {
						this.onImageFail(res, file);
						reject();
					})
					this.$nextTick(() => this.$refs.chatInputEditor.focus());
					this.scrollToBottom();
					});
			},
			async sendTextMessage(sendText, atUserIds) {
				if (!sendText.trim()) {
					return;
				}

				let msgInfo = {
					content: sendText,
					type: 0,
					sendTime: new Date().getTime(),
					selfSend: true,
					sendId: this.mine.id
				}

				// 填充对方id
				this.fillTargetId(msgInfo, this.chat.targetId);

				// 被@人员列表
				if (this.chat.type == "GROUP") {
					msgInfo.atUserIds = atUserIds;
					msgInfo.receipt = this.isReceipt;
				}

				// 添加引用消息ID
				if (this.$refs.chatInputEditor?.quoteMessage?.quoteMessage?.id) {
					msgInfo.quoteId = this.$refs.chatInputEditor.quoteMessage.quoteMessage.id;
				}

				this.lockMessage = true;

				this.sendMessageRequest(msgInfo).then((m) => {
					m.selfSend = true;
					this.$store.commit("insertMessage", m);
					this.moveChatToTop();
					this.scrollToBottom();
				}).catch(error => {
					console.error('发送消息失败:', error);
					this.$message.error('发送失败');
				}).finally(() => {
					this.lockMessage = false;
					this.isReceipt = false;
				});
			},
			sendFileMessage(file) {
				return new Promise((resolve,reject)=>{
					let check = this.$refs.fileUpload.beforeUpload(file);
					if (check) {
						this.$refs.fileUpload.onFileUpload({ file });
					}
				})
			},
			deleteMessage(msgInfo) {
				this.$confirm('确认删除消息?', '删除消息', {
					confirmButtonText: '确定',
					cancelButtonText: '取消',
					type: 'warning'
				}).then(() => {
					this.$store.commit("deleteMessage", msgInfo);
				});
			},
			recallMessage(msgInfo) {
				this.$confirm('确认撤回消息?', '撤回消息', {
					confirmButtonText: '确定',
					cancelButtonText: '取消',
					type: 'warning'
				}).then(() => {
					let url = `/message/${this.chat.type.toLowerCase()}/recall/${msgInfo.id}`
					this.$http({
						url: url,
						method: 'delete'
					}).then(() => {
						this.$message.success("消息已撤回");
						msgInfo = JSON.parse(JSON.stringify(msgInfo));
						msgInfo.type = 10;
						msgInfo.content = '你撤回了一条消息';
						msgInfo.status = this.$enums.MESSAGE_STATUS.RECALL;
						this.$store.commit("insertMessage", msgInfo);
					}).catch(() => {
						this.$message.error("撤回失败");
					})
				});
			},
			onRecallthisMessage(msgInfo) {
				let url = `/message/${this.chat.type.toLowerCase()}/recallAdmin/${msgInfo.id}`;
				this.$http({
					url: url,
					method: 'DELETE'
				}).then((res) => {
					this.$message.success("消息已撤回");
					msgInfo = JSON.parse(JSON.stringify(msgInfo));
					msgInfo.type = 10;
					msgInfo.content = '你撤回了一条消息';
					msgInfo.status = this.$enums.MESSAGE_STATUS.RECALL;
					this.$store.commit("insertMessage", msgInfo);
				}).catch((error) => {
					console.error('撤回消息失败:', error);
					this.$message.error("撤回失败");
				});
			},
			readedMessage() {
				if (this.chat.unreadCount == 0) {
					return;
				}
				this.$store.commit("resetUnreadCount", this.chat)
				if (this.chat.type == "GROUP") {
					var url = `/message/group/readed?groupId=${this.chat.targetId}`
				} else {
					url = `/message/private/readed?friendId=${this.chat.targetId}`
				}
				this.$http({
					url: url,
					method: 'put'
				}).then(() => {})
			},
			loadReaded(fId) {
				this.$http({
					url: `/message/private/maxReadedId?friendId=${fId}`,
					method: 'get'
				}).then((id) => {
					this.$store.commit("readedMessage", {
						friendId: fId,
						maxId: id
					});
				});
			},
			loadGroup(groupId) {
				// 验证groupId是否有效
				if (!groupId) {
					console.error('无效的群组ID');
					this.$message.error('无法加载群组，ID无效');
					return;
				}
				
				// 设置加载状态
				this.contentLoading = true;
				// membersLoading 状态只在初始化时设置，后续由 ChatGroupSide 组件负责管理
				console.log("加载群聊信息:", groupId);
				
				// 恢复原有的群组信息加载
				this.$http({
					url: `/group/find/${groupId}`,
					method: 'get'
				}).then((group) => {
					if (!group) {
						throw new Error('接收到的群组数据为空');
					}
					
					this.group = group;
					//this.group.id = group.zid;
					this.$store.commit("updateChatFromGroup", group);
					this.$store.commit("updateGroup", group);
					// 增加renderKey，强制消息组件重新渲染
					this.renderKey++;
				}).catch(error => {
					// 如果加载失败，则删除当前聊天
					console.error('Failed to load group info:', error);
					this.$message.error(`加载群组信息失败: ${error.message || '未知错误'}`);
					
					if (this.chat && this.chat.targetId) {
						this.$store.commit("removeGroupChat", this.chat.targetId);
					}
				}).finally(() => {
					// 仅结束群组信息加载状态，不影响成员加载状态
					this.contentLoading = false;
					// 注意：不在这里设置 membersLoading = false
				});
				
				// 加载群成员信息 - 由 ChatGroupSide 组件负责设置 membersLoading = false
				this.$http({
					url: `/group/members/${groupId}`,
					method: 'get'
				}).then((groupMembers) => {
					if (!groupMembers || !Array.isArray(groupMembers)) {
						throw new Error('接收到的群组成员数据格式不正确');
					}
					
					this.groupMembers = groupMembers;
					// 增加renderKey，强制消息组件重新渲染
					this.renderKey++;
					// 强制当前组件重新渲染，确保所有消息使用最新头像
					this.$forceUpdate();
					console.log(`已加载 ${groupMembers.length} 名群成员，等待 ChatGroupSide 组件处理并关闭加载状态`);
					// 发送群成员加载完成事件
					emitter.emit('group-members-loaded', {
						groupId: groupId,
						memberCount: groupMembers.length
					});
				}).catch(error => {
					console.error('Failed to load group members:', error);
					this.$message.error(`加载群成员失败: ${error.message || '未知错误'}`);
					this.groupMembers = [];
					// 失败时也不直接设置 membersLoading = false
				});
				
				// 再次强制组件更新，确保显示最新信息
				this.$nextTick(() => {
					this.renderKey++;
					this.$forceUpdate();
				});
			},
			loadFriend(friendId) {
				// 设置加载状态
				this.contentLoading = true;
				console.log("加载好友信息:", friendId);
				
				// 添加防抖，避免短时间内多次请求
				if (this.friendLoadTimer) {
					clearTimeout(this.friendLoadTimer);
				}
				
				this.friendLoadTimer = setTimeout(() => {
					// 获取对方最新信息
					this.$http({
						url: `/user/find/${friendId}`,
						method: 'get'
					}).then((friend) => {
						// 立即增加renderKey，强制消息组件重新渲染
						this.renderKey++;
						
						// 比较新旧头像，只有当有变化时才更新
						const needUpdate = !this.friend || 
							this.friend.headImage !== friend.headImage || 
							this.friend.nickName !== friend.nickName;
						
						this.friend = friend;
						
						if (needUpdate) {
							// 更新会话信息
							this.$store.commit("updateChatFromFriend", friend);
							this.$store.commit("updateFriend", friend);
							
							// 再次增加renderKey，强制消息组件重新渲染
							this.renderKey++;
							
							// 强制当前组件重新渲染，确保所有消息使用最新头像
							this.$forceUpdate();
							
							console.log('Friend info updated:', friend.nickName, friend.headImage);
						}
					}).catch(error => {
						// 如果加载失败，则删除当前聊天
						console.error('Failed to load friend info:', error);
					}).finally(() => {
						// 结束好友信息加载状态
						this.contentLoading = false;
					});
				}, 300); // 300ms防抖
			},
			showName(msgInfo) {
				if (this.chat.type == 'GROUP') {
					let member = this.groupMembers.find((m) => m.userId == msgInfo.sendId);
					return member ? member.showNickName : "";
				} else {
					// 如果是自己发送的消息，使用自己的昵称
					if (msgInfo.sendId == this.mine.id) {
						return this.mine.nickName;
					}
					// 如果是好友发送的消息，优先使用this.friend中的最新昵称
					else if (this.friend && this.friend.nickName) {
						return this.friend.nickName;
					}
					// 后备方案：使用chat中的昵称
					else {
						return this.chat.showName;
					}
				}
			},
			headImage(msgInfo) {
				if (this.chat.type == 'GROUP') {
					let member = this.groupMembers.find((m) => m.userId == msgInfo.sendId);
					return member ? member.headImage : "";
				} else {
					// 如果是自己发送的消息，使用自己的头像
					if (msgInfo.sendId == this.mine.id) {
						return this.mine.headImage;
					} 
					// 如果是好友发送的消息，优先使用this.friend中的最新头像
					else if (this.friend && this.friend.headImage) {
						return this.friend.headImage;
					}
					// 后备方案：使用chat中的头像
					else {
						return this.chat.headImage;
					}
				}
			},
			resetEditor() {
				this.sendImageUrl = "";
				this.$nextTick(() => {
					if(this.flag){
					 	this.$refs.chatInputEditor.clear();
						this.$refs.chatInputEditor.focus();
					}
				});
			},
			scrollToBottom() {
				console.log("尝试滚动到底部");
				
				this.$nextTick(() => {
					try {
						// 使用ref访问DOM元素
						if (this.$refs.bottomAnchor) {
							// 直接滚动到底部锚点
							this.$refs.bottomAnchor.scrollIntoView({ behavior: 'auto', block: 'end' });
							console.log("使用底部锚点滚动");
							return;
						}
						
						// 备用方法
						if (this.$refs.chatScrollBox) {
							const chatBox = this.$refs.chatScrollBox;
							console.log("聊天容器高度:", chatBox.scrollHeight, "当前滚动位置:", chatBox.scrollTop);
							chatBox.scrollTop = chatBox.scrollHeight;
							return;
						}
						
						// 最后再尝试使用getElementById
						const chatBox = document.getElementById("chatScrollBox");
						if (chatBox) {
							chatBox.scrollTop = chatBox.scrollHeight;
							
							// 额外保障
							setTimeout(() => {
								chatBox.scrollTop = chatBox.scrollHeight;
							}, 100);
						} else {
							console.warn("找不到聊天容器元素");
						}
					} catch (error) {
						console.error("滚动到底部时出错:", error);
					}
				});
			},
			refreshPlaceHolder() {
				if (this.isReceipt) {
					this.placeholder = "【回执消息】"
				} else if (this.$refs.editBox && this.$refs.editBox.innerHTML) {
					this.placeholder = ""
				} else {
					this.placeholder = "聊点什么吧~";
				}
			},
			sendMessageRequest(msgInfo){
				return  new Promise((resolve,reject)=>{
					// 请求入队列，防止请求"后发先至"，导致消息错序
					this.reqQueue.push({msgInfo,resolve,reject});
					this.processReqQueue();
				})
			},
			processReqQueue(){
				if (this.reqQueue.length && !this.isSending) {
					this.isSending = true;
					const reqData = this.reqQueue.shift();
					this.$http({
						url: this.messageAction,
						method: 'post',
						data: reqData.msgInfo
					}).then((res)=>{
						reqData.resolve(res)
					}).catch((e)=>{
						reqData.reject(e)
					}).finally(()=>{
						this.isSending = false;
						// 发送下一条请求
						this.processReqQueue();
					})
				}
			},
			sendMessageRequest2(msgInfo) {
				return new Promise((resolve, reject) => {
					// 请求入队列，防止请求"后发先至"，导致消息错序
					this.reqQueue = this.reqQueue || [];
					this.reqQueue.push({msgInfo, resolve, reject});
					this.processReqQueue2();
				});
			},
			processReqQueue2() {
				if (this.reqQueue && this.reqQueue.length && !this.isSending) {
					this.isSending = true;
					const reqData = this.reqQueue.shift();
					let requestUrl = `/message/${reqData.msgInfo.chatType.toLowerCase()}/send`;
					this.$http({
						url: requestUrl,
						method: 'post',
						data: reqData.msgInfo
					}).then((res) => {
						if (reqData.msgInfo.type == this.$enums.MESSAGE_TYPE.TEXT) {
							reqData.msgInfo.selfSend = true;
						}
						reqData.msgInfo.sendNickName = res.sendNickName;
						reqData.msgInfo.loadStatus = 'ok';
						reqData.msgInfo.id = res.id;
						reqData.msgInfo.sendId = res.sendId;
						
						// 插入消息到聊天记录
						setTimeout(() => {
							this.$store.commit('insertMessage', reqData.msgInfo);
						}, 2000);
						
						reqData.resolve(res);
					}).catch((e) => {
						reqData.reject(e);
					}).finally(() => {
						this.isSending = false;
						// 发送下一条请求
						this.processReqQueue2();
					});
				}
			},
			generateId() {
				return String(new Date().getTime()) + String(Math.floor(Math.random() * 1000));
			},
			onFocus() {
				this.readedMessage()
			},
			handleVisibilityChange() {
				if(!document.visibilityState == 'hidden'){
					this.readedMessage()
				}else{
					console.log('222')
				}
			},
			getInfo(gid,type){
				this.gAPI.isprohibition(gid,type).then(data=>{
					if(data){
						// 在 Vue 3 中直接赋值即可实现响应式更新
						this.isProhibition = data === '1' || data === '2';
						this.sendText = data === '1' ? "全  员   禁   言" : 
								data === '2' ? "已  被   禁   言" : "";
						this.stylea = data === '0' ? "" : "center";
						
						// 确保视图更新
						this.$nextTick(() => {
							if(this.$refs.chatInputEditor) {
								// 发送状态变化事件
								this.$refs.chatInputEditor.$emit('prohibition-changed', this.isProhibition);
							}
						});
					}
				});
				let params={
					groupId:gid
				}
				this.gmAPI.getPermission(params).then(res=>{
					this.isadmin = res;
				});
			},
			handleProhibitionUpdate(data) {
				if(this.chat && this.chat.type === 'GROUP' && this.chat.targetId === data.groupId) {
					this.getInfo(data.groupId, data.type);
					// 确保子组件更新
					this.$nextTick(() => {
						if(this.$refs.chatInputEditor) {
							this.$refs.chatInputEditor.$emit('prohibition-changed', this.isProhibition);
						}
					});
					}
				},
			// 节流函数
			throttle(fn, delay) {
				let last = 0;
				return function(...args) {
					const now = Date.now();
					if (now - last >= delay) {
						last = now;
						fn.apply(this, args);
					}
				};
			},

			// 初始化虚拟滚动
			initVirtualScroll() {
				this.updateVisibleMessages();
				
				// 使用 Intersection Observer 优化滚动性能
				const observer = new IntersectionObserver((entries) => {
					entries.forEach(entry => {
						if (entry.isIntersecting) {
							const msgId = entry.target.getAttribute('data-msg-id');
							if (msgId) {
								this.loadMessageChunk(parseInt(msgId));
							}
						}
					});
				}, this.observerOptions);

				// 观察消息容器
				const messageElements = document.querySelectorAll('.chat-message-item');
				messageElements.forEach(el => observer.observe(el));
			},

			// 更新可见消息列表
			updateVisibleMessages() {
				const startIdx = Math.max(0, this.showMinIdx);
				const endIdx = Math.min(startIdx + this.messageChunkSize, this.chat.messages.length);
				this.visibleMessages = this.chat.messages.slice(startIdx, endIdx);
			},

			// 加载消息块
			loadMessageChunk(msgId) {
				const startIdx = Math.max(0, msgId - this.messageChunkSize / 2);
				const endIdx = Math.min(startIdx + this.messageChunkSize, this.chat.messages.length);
				this.visibleMessages = this.chat.messages.slice(startIdx, endIdx);
			},

			// 加载更多消息
			loadMoreMessages() {
				if (this.isLoading) return;
				
				this.isLoading = true;
				// 这里可以添加加载更多消息的逻辑
				
				setTimeout(() => {
					this.isLoading = false;
				}, 500);
			},
			toggleSide() {
				this.showSide = !this.showSide;
				console.log('Drawer state:', this.showSide); // 添加调试日志
			},
			// 监听消息中的图片和附件加载
			setupMediaLoadListeners() {
				this.$nextTick(() => {
					// 获取聊天消息容器
					const chatBox = document.getElementById("chatScrollBox");
					if (!chatBox) return;
					
					// 查找所有图片
					const images = chatBox.querySelectorAll('img');
					for (let img of images) {
						if (!img.complete) {
							img.addEventListener('load', () => {
								// 图片加载完成后滚动到底部
								this.scrollToBottom();
							});
						}
					}
					
					// 查找所有视频、音频等媒体元素
					const mediaElements = chatBox.querySelectorAll('video, audio');
					for (let media of mediaElements) {
						media.addEventListener('loadeddata', () => {
							// 媒体加载完成后滚动到底部
							this.scrollToBottom();
						});
					}
				});
			},
			handleFriendInfoUpdate(friendId) {
				// 只有当前聊天是私聊，且是当前好友时，才重新加载好友信息
				if (this.chat.type === 'PRIVATE' && this.chat.targetId === friendId) {
					// 防抖处理，避免短时间内多次触发
					if (this.friendUpdateTimer) {
						clearTimeout(this.friendUpdateTimer);
					}
					
					this.friendUpdateTimer = setTimeout(() => {
						// 加载最新好友信息
						this.loadFriend(friendId);
					}, 500);
				}
			},
			handleGroupInfoUpdate(groupId) {
				// 只有当前聊天是群聊，且是当前群时，才重新加载群信息
				if (this.chat.type === 'GROUP' && this.chat.targetId === groupId) {
					this.loadGroup(groupId);
					
					// 即使没有立刻加载到最新信息，先增加renderKey来强制刷新消息
					this.renderKey++;
				}
			},
			startGroupCall() {
				// 创建群组语音通话
				console.log("创建群组语音通话", this.showSide);
				if (!this.group || !this.group.id) {
					this.$message.error('群组信息不完整，无法发起通话');
					return;
				}
				
				this.$http({
					url: "/webrtc/group/info?groupId=" + this.group.id,
					method: "get"
				}).then((info)=> {
					if (info.isChating) {
						// 已在通话中，可以直接加入通话
						this.$refs.rtcJoin.open(info);
					} else {
						// 邀请成员发起通话
						let ids = [this.mine.id];
						let maxChannel = this.$store.state.configStore.webrtc.maxChannel;
						this.$refs.rtcSel.open(maxChannel, ids, ids);
					}
				}).catch((error) => {
					console.error('Failed to start group call:', error);
					this.$message.error('无法发起群组通话');
				});
			},
			onInviteRtc(type) {
				if (!this.group || !this.group.id) {
					this.$message.error('群组信息不完整，无法发起通话');
					return;
				}
				
				this.$refs.rtcSel.show({
					groupId: this.group.id,
					type: type
				});
			},
		},
		computed: {
			mine() {
				return this.$store.state.userStore.userInfo;
			},
			title() {
				let title = this.chat.showName;
				if (this.chat.type == "GROUP") {
					let size = this.groupMembers.filter(m => !m.quit).length;
					title += `(${size})`;
				}
				return title;
			},
			messageAction() {
				return `/message/${this.chat.type.toLowerCase()}/send`;
			},
			unreadCount() {
				return this.chat.unreadCount;
			},
			isPermission() {
				return this.chat.type == "GROUP" && this.group.adminId == this.mine.id;
			},
			messageSize() {
				if (!this.chat || !this.chat.messages) {
					return 0;
				}
				return this.chat.messages.length;
			},
			groupList() {
				return this.$store.state.groupStore.groups.find(g => g.id == this.chat.targetId);
			},
			// 判断是否是群主或管理员
			isAdmin() {
				if (this.chat.type !== 'GROUP') return false;
				
				// 是群主
				if (this.group.ownerId === this.mine.id) return true;
				
				// 是管理员
				const currentMember = this.groupMembers.find(m => m.userId === this.mine.id);
				return currentMember?.isAdmin === 'Y';
			}
		},
		watch: {
			chat: {
				handler(newChat, oldChat) {
					if (newChat.targetId > 0 && (!oldChat || newChat.type != oldChat.type ||
							newChat.targetId != oldChat.targetId)) {
						// 设置加载状态
						this.contentLoading = true;
						
						if (this.chat.type == "GROUP") {
							// 只有在切换到新的群聊时设置 membersLoading = true
							// 后续的管理由 ChatGroupSide 组件负责
							console.log('切换到群聊，初始设置 membersLoading = true');
							this.membersLoading = true;
							this.getInfo(this.chat.targetId,this.chat.type);//查询禁言状态
							this.loadGroup(this.chat.targetId);
						
						} else {
							// 避免重复加载相同的好友
							if (this.lastFriendId !== this.chat.targetId) {
								this.lastFriendId = this.chat.targetId;
								this.loadFriend(this.chat.targetId);
								// 加载已读状态
								this.loadReaded(this.chat.targetId);
							}
						}
						
						// 消息已读
						this.readedMessage();
						this.showSide = false;
						
						// 初始状态只显示30条消息
						let size = this.chat.messages.length;
						this.showMinIdx = size > 30 ? size - 30 : 0;
						
						// 重置输框
						this.resetEditor();
						
						// 复位回执消息
						this.isReceipt = false;
						
						// 更新placeholder
						this.refreshPlaceHolder();
						
						// 确保DOM更新后滚动到底部
						this.$nextTick(() => {
							console.log("Chat changed, scrolling to bottom");
							this.scrollToBottom();
							
							// 额外保证，防止初次渲染后元素高度计算不准确
							setTimeout(() => {
								this.scrollToBottom();
							}, 200);
						});
					}
				},
				immediate: true
			},
			messageSize: {
				handler(newSize, oldSize) {
					if (newSize > oldSize) {
						console.log("Message size changed:", newSize, oldSize);
						// 确保DOM更新后滚动到底部
						this.$nextTick(() => {
							this.scrollToBottom();
						});
					}
				}
			},
			//禁言状态
			isProhibition: {
				handler(newVal) {
					this.$nextTick(() => {
						if(this.$refs.chatInputEditor) {
							this.$refs.chatInputEditor.$emit('prohibition-changed', newVal);
							this.$refs.chatInputEditor.$forceUpdate();
						}
					});
				},
				immediate: true
			}
		},
		mounted() {
			// 设置消息列表的虚拟滚动
			this.initVirtualScroll();
			// 添加滚动事件监听
			document.getElementById('chatScrollBox').addEventListener('scroll', this.throttledScrollHandler);
			document.addEventListener('visibilitychange', this.handleVisibilityChange);
			// 添加禁言状态更新事件监听
			emitter.on('updateProhibitionStatus', this.handleProhibitionUpdate);
			
			// 添加好友信息更新事件监听
			emitter.on('friendInfoUpdated', this.handleFriendInfoUpdate);
			// 添加群聊信息更新事件监听
			emitter.on('groupInfoUpdated', this.handleGroupInfoUpdate);
			
			// 确保初始加载时滚动到底部
			this.scrollToBottom();
			
			// 监听窗口大小变化，确保滚动位置正确
			window.addEventListener('resize', this.scrollToBottom);
			
			// 监听消息中的图片和附件加载
			this.setupMediaLoadListeners();
			
			// 使用MutationObserver监听DOM变化，在消息列表变化时自动滚动
			this.$nextTick(() => {
				const chatBox = document.getElementById('chatScrollBox');
				if (chatBox) {
					const config = { childList: true, subtree: true };
					
					// 创建一个新的MutationObserver
					const observer = new MutationObserver((mutationsList) => {
						// 检查是否有新消息添加
						let shouldScroll = false;
						for (const mutation of mutationsList) {
							if (mutation.type === 'childList' && mutation.addedNodes.length > 0) {
								shouldScroll = true;
								break;
							}
						}
						
						// 如果有新消息添加，则滚动到底部
						if (shouldScroll) {
							this.scrollToBottom();
						}
					});
					
					// 开始观察聊天容器的变化
					observer.observe(chatBox, config);
					
					// 保存observer引用以便在组件销毁时断开连接
					this.domObserver = observer;
				}
			});
		},
		beforeUnmount() {
			// 移除滚动事件监听
			const chatBox = document.getElementById('chatScrollBox');
			if (chatBox) {
				chatBox.removeEventListener('scroll', this.throttledScrollHandler);
			}
			
			// 移除其他事件监听
			document.removeEventListener('visibilitychange', this.handleVisibilityChange);
			window.removeEventListener('resize', this.scrollToBottom);
			
			// 移除事件总线监听
			emitter.off('updateProhibitionStatus', this.handleProhibitionUpdate);
			emitter.off('friendInfoUpdated', this.handleFriendInfoUpdate);
			emitter.off('groupInfoUpdated', this.handleGroupInfoUpdate);
			
			// 清除所有定时器
			if (this.friendLoadTimer) {
				clearTimeout(this.friendLoadTimer);
			}
			if (this.friendUpdateTimer) {
				clearTimeout(this.friendUpdateTimer);
			}
			
			// 断开DOM观察器
			if (this.domObserver) {
				this.domObserver.disconnect();
			}
		}
	}
</script>

<style lang="scss">
	.chat-box {
		position: relative;
		width: 100%;
		background: #f8f8f8;
		border: #dddddd solid 1px;
		display: flex;
		flex-direction: column;
		height: 100%;

		.el-container {
			height: 100%;
			flex-direction: column;
		}

		.content-box {
			height: 100%;
			flex-direction: column;
			overflow: hidden;
		}

		.el-header {
			padding: 3px;
			background-color: white;
			line-height: 50px;
			font-size: 20px;
			font-weight: 600;
			border-bottom: 1px #ddd solid;
			flex-shrink: 0;
			display: flex;
			justify-content: space-between;
			align-items: center;

			.header-actions {
				display: flex;
				align-items: center;
			}

			.header-btn {
				padding: 0 10px;
				margin-right: 10px;
				font-size: 14px;
				color: #606266;
				cursor: pointer;
				transition: all 0.2s;
				
				&:hover {
					color: #409EFF;
				}
			}

			.btn-side {
				line-height: 50px;
				font-size: 25px;
				cursor: pointer;
				display: flex;
				align-items: center;
				justify-content: center;
				height: 50px;
				width: 50px;
				
				.el-icon {
					font-size: 22px;
					color: #555;
					transition: color 0.2s;
				}
				
				&:hover .el-icon {
					color: #409EFF;
				}
			}
		}

		.im-chat-main {
			padding: 0;
			background-color: #f8f8f8;
			overflow-y: auto;
			flex: 1;
			height: calc(100% - 40px); /* 减去工具栏的高度 */

			.im-chat-box {
				height: 100%;
				overflow-y: auto;
				>ul {
					padding: 0 20px;
					height: auto;
					min-height: 100%;

					li {
						list-style-type: none;
					}
				}
			}
		}

		.im-chat-footer {
			display: flex;
			flex-direction: column;
			padding: 0;

			.chat-tool-bar {
				display: flex;
				position: relative;
				width: 100%;
				height: 40px;
				text-align: left;
				box-sizing: border-box;
				border-top: 1px solid #e7e7e7;
				border-bottom: 1px solid #e7e7e7;
				padding: 0;
				background-color: #f5f5f5;
				justify-content: flex-start;
				align-items: center;
				padding-left: 10px;

				.tool-icon-btn {
					width: 30px;
					height: 30px;
					margin-right: 15px;
					display: flex;
					align-items: center;
					justify-content: center;
					cursor: pointer;
					transition: all 0.2s;
					color: #555;
					
					.el-icon {
						font-size: 20px;
					}
					
					&:hover {
						color: #409EFF;
					}
					
					&.active {
						color: #409EFF;
					}
					
					&.disabled {
						opacity: 0.5;
						cursor: not-allowed;
						color: #999;
					}
				}
				
				.tool-container {
					height: 100%;
					display: flex;
					align-items: center;
				}
			}

			.send-content-area {
				position: relative;
				display: flex;
				flex-direction: column;
				height: 100%;
				background-color: white !important;

				.send-text-area {
					box-sizing: border-box;
					padding: 5px;
					width: 100%;
					flex: 1;
					resize: none;
					font-size: 16px;
					color: black;
					outline: none;

					text-align: left;
					line-height: 30px;

					&:before {
						content: attr(placeholder);
						color: gray;
					}

					.at {
						color: blue;
						font-weight: 600;
					}

					.receipt {
						color: darkblue;
						font-size: 15px;
						font-weight: 600;
					}

					.emo {
						width: 30px;
						height: 30px;
						vertical-align: bottom;
					}
				}

				.send-image-area {
					text-align: left;
					//border: #53a0e7 solid 1px;

					.send-image-box {
						position: relative;
						display: inline-block;

						.send-image {
							max-height: 180px;
							border: 1px solid #ccc;
							border-radius: 2%;
							margin: 2px;
						}

						.send-image-close {
							position: absolute;
							padding: 3px;
							right: 7px;
							top: 7px;
							color: white;
							cursor: pointer;
							font-size: 15px;
							font-weight: 600;
							background-color: #aaa;
							border-radius: 50%;
							border: 1px solid #ccc;
						}
					}
				}

				.send-btn-area {
					padding: 10px;
					position: absolute;
					bottom: 0;
					right: 0;
				}
			}
		}
	}

	.chat-msg-file {
		display: flex;
		flex-wrap: nowrap;
		flex-direction: row;
		align-items: center;
		cursor: pointer;
		padding-bottom: 5px;

		.chat-file-box {
			position: relative;
			display: flex;
			flex-wrap: nowrap;
			align-items: center;
			min-height: 80px;
			box-shadow: 5px 5px 2px #c0c0c0;
			border: #dddddd solid 1px;
			border-radius: 6px;
			background-color: #eeeeee;
			padding: 10px 15px;

			.chat-file-info {
				flex: 1;
				height: 100%;
				text-align: left;
				font-size: 14px;

				.chat-file-name {
					display: inline-block;
					min-width: 150px;
					max-width: 300px;
					font-size: 16px;
					font-weight: 600;
					margin-bottom: 15px;
					white-space: pre-wrap;
					word-break: break-all;
				}
			}

			.chat-file-icon {
				font-size: 50px;
				color: #d42e07;
			}

			.delete-icon {
				position: absolute;
				top: -10px;
				right: -10px;
				width: 20px;
				height: 20px;
				background-color: #f56c6c;
				border-radius: 50%;
				display: flex;
				align-items: center;
				justify-content: center;
				cursor: pointer;
				transition: all 0.3s;

				.el-icon {
					color: white;
					font-size: 12px;
				}

				&:hover {
					background-color: #f78989;
					transform: scale(1.1);
				}
			}
		}

		.send-fail {
			color: #e60c0c;
			font-size: 30px;
			cursor: pointer;
			margin: 0 20px;
		}
	}

	.bottom-anchor {
		height: 1px;
		margin: 0;
		padding: 0;
		visibility: hidden; /* 使元素不可见但仍占据空间 */
	}
</style>